home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
shells
/
guest-0.000
/
guest-0
/
guest-0.2
/
parse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-08
|
7KB
|
265 lines
/*
Parses menu file into a linked list
Copyright (C) 1995 Brian Cully
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 675 Mass
Ave, Cambridge, MA 02139, USA.
please send patches or advice to: `shmit@meathook.intac.com'
*/
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#include "parse.h"
static void error(char *message, int lineno) {
fprintf(stderr, "%i: %s", lineno, message);
exit(1);
}
static void alloc_items(struct menu_items **data, const char *line, int i) {
int worddex;
char *word = (char *)malloc(255);
char errmess[255];
/* Skip white space */
line += strwhite(line);
if ((worddex = substr(line,word,':')) == -1)
error("Premature end-of-line\n", i);
/* Advance past word */
line += worddex+1;
/* Scan for tokens, then dissemate information */
if (!strcmp(word, MENU_OP_TITLE)) {
if (substr(line,word,':') == -1)
error("Premature end-of-line\n",i);
(*data)->type = MENU_TITLE;
(*data)->name = (char *)malloc(strlen(word)+1);
strcpy((*data)->name, word);
(*data)->args = NULL;
} else if (!strcmp(word, MENU_OP_SUB)) {
if ((worddex = substr(line,word,':')) == -1)
error("Premature end-of-line\n",i);
line += worddex + 1;
(*data)->type = MENU_SUB;
(*data)->name = (char *)malloc(strlen(word)+1);
strcpy((*data)->name, word);
if (substr(line,word,':') == -1)
error("Premature end-of-line\n",i);
(*data)->args = (char *)malloc(strlen(word) + 1);
strcpy((*data)->args, word);
} else if (!strcmp(word, MENU_OP_NOP)) {
if (substr(line,word,':') == -1)
error("Premature end-of-line\n", i);
(*data)->type = MENU_NOP;
(*data)->name = (char *)malloc(strlen(word)+1);
strcpy((*data)->name, word);
(*data)->args = NULL;
} else if (!strcmp(word, MENU_OP_EXEC)) {
if ((worddex = substr(line,word,':')) == -1)
error("Premature end-of-line\n",i);
line += worddex + 1;
(*data)->type = MENU_EXEC;
(*data)->name = (char *)malloc(strlen(word)+1);
strcpy((*data)->name, word);
if (substr(line,word,':') == -1)
error("Premature end-of-line\n",i);
(*data)->args = (char *)malloc(strlen(word) + 1);
strcpy((*data)->args, word);
} else if (!strcmp(word, MENU_OP_EXIT)) {
if (substr(line,word,':') == -1)
error("Premature end-of-line\n",i);
(*data)->type = MENU_EXIT;
(*data)->name = (char *)malloc(strlen(word)+1);
strcpy((*data)->name, word);
(*data)->args = NULL;
} else {
sprintf(errmess, "Unknown token `%s'\n", word);
error(errmess, i);
}
/* Allocate another link */
(*data)->next = (struct menu_items*)malloc(sizeof(struct menu_items));
(*data)->next->prev = *data;
*data = (*data)->next;
(*data)->next = NULL;
free(word);
}
/* Parses the file into a linked menu list
** On entry:
** menuptr == empty pointer to list
** menufile == loaded menu file
** On exit:
** menuptr == full menu, in linked list
** returns -1 on error, 0 otherwise
*/
int parsefile(struct menu **menuptr,char *menufile) {
char *line, *word;
int index,i=0;
line = (char *)malloc(255);
word = (char *)malloc(255);
*menuptr = (struct menu *)malloc(sizeof(struct menu));
(*menuptr)->prev = NULL;
(*menuptr)->next = NULL;
(*menuptr)->data = NULL;
while ((index = substr(menufile,line,CR)) != -1) {
int worddex, menu_close;
i++;
menufile += index+1;
/* Should probably put a '#' -> '\0' replacement in here */
if ((worddex = substr(line, word, ' ')) == 0) {
fprintf(stderr, "%i: premature end-of-line\n", i);
return(-1);
}
line += worddex + 1;
if (!strcmp(word,MENU_BEGIN)) {
if (substr(line, word, ' ') == 0) {
fprintf(stderr, "%i: premature end-of-line\n", i);
return(-1);
}
/* Store menu name, for easy retrieval */
(*menuptr)->name = (char *)malloc(strlen(word)+1);
strcpy((*menuptr)->name, word);
/* Loop through, defining menu, quit at MENU_END */
(*menuptr)->data = (struct menu_items *)malloc(sizeof(struct menu_items));
(*menuptr)->data->next = NULL;
(*menuptr)->data->prev = NULL;
menu_close = 0;
while (!menu_close) {
/* Error on EOF, it doesnt belong here */
if ((index = substr(menufile,line,CR)) == -1)
error("Premature end-of-file\n", i);
/* Advance past line */
menufile += index+1;
i++;
/* Close menu on MENU_END, otherwise define node */
if (!strcmp(line,MENU_END)) {
menu_close = 1;
} else {
alloc_items(&((*menuptr)->data), line, i);
}
}
/* Free last link */
if ((*menuptr)->data->prev == NULL) {
free((*menuptr)->data);
(*menuptr)->data = NULL;
} else {
(*menuptr)->data = (*menuptr)->data->prev;
free((*menuptr)->data->next);
(*menuptr)->data->next = NULL;
/* rewind linked list */
while ((*menuptr)->data->prev != NULL)
(*menuptr)->data = (*menuptr)->data->prev;
}
/* Allocate another link */
(*menuptr)->next = (struct menu *)malloc(sizeof(struct menu));
(*menuptr)->next->prev = *menuptr;
*menuptr = (*menuptr)->next;
(*menuptr)->next = NULL;
(*menuptr)->data = NULL;
}
}
/* Free last link */
if ((*menuptr)->prev == NULL) {
free(*menuptr);
*menuptr = NULL;
} else {
*menuptr = (*menuptr)->prev;
free((*menuptr)->next);
(*menuptr)->next = NULL;
/* rewind linked list */
while ((*menuptr)->prev != NULL)
*menuptr = (*menuptr)->prev;
}
/* free variables */
free(word);
free(line);
return(0);
}
/* frees up allocated memory
** On entry:
** menuptr == linked menu list
** menufile == loaded menu file
** On Exit:
** nothing, DONT USE menuptr OR menufile without allocating them again
*/
void freemem(struct menu *menuptr, char *menufile) {
free(menufile);
while (menuptr != NULL) {
struct menu *p;
p = menuptr;
menuptr = menuptr->next;
while (p->data != NULL) {
struct menu_items *q;
q = p->data;
p->data = p->data->next;
if (q->name != NULL)
free(q->name);
if (q->args != NULL)
free(q->args);
free(q);
}
free(p->name);
free(p);
}
}